﻿using LD.Common;
using LD.Host;
using LdCommunication;
using LdCommunication.Profinet.Panasonic;
using System;
using System.Threading.Tasks;

namespace LD.PLC
{
    public class PanasonicMC : PLCAbstract
    {
        private PanasonicMcNet mc;
        private HDParamModel hDParam;
        private ConnStatus connStatus = ConnStatus.断线;
        private bool start;
        private Task task;
        public PanasonicMC()
        {
            mc = new PanasonicMcNet();
        }
        public override ConnStatus ConnStatus {
            get { return connStatus; }
            set
            {
                connStatus = value;
                ConnStatusEvent?.Invoke(value);
            }
        }

        public override event Action<ConnStatus> ConnStatusEvent;

        public override OperateResult<byte[]> Read(string address, ushort val)
        {
            return mc.Read(address, val);
        }

        public override OperateResult<bool[]> ReadBool(string address, ushort val)
        {
            return mc.ReadBool(address, val);
        }

        public override OperateResult<bool> ReadBool(string address)
        {
            return mc.ReadBool(address);
        }

        public override OperateResult<float> ReadFloat(string address)
        {
            return mc.ReadFloat(address);
        }

        public override OperateResult<float[]> ReadFloat(string address, ushort val)
        {
            return mc.ReadFloat(address, val);
        }

        public override OperateResult<int> ReadInt(string address)
        {
            return mc.ReadInt32(address);
        }

        public override OperateResult<int[]> ReadInt(string address, ushort val)
        {
            return mc.ReadInt32(address, val);
        }

        public override OperateResult<short> ReadInt16(string address)
        {
            return mc.ReadInt16(address);
        }

        public override OperateResult<short[]> ReadInt16(string address, ushort val)
        {
            return mc.ReadInt16(address, val);
        }

        public override OperateResult<string> ReadString(string address, ushort val)
        {
            return mc.ReadString(address, val);
        }

        public override void Start(dynamic param)
        {
            hDParam = param as HDParamModel;
            mc.IpAddress = hDParam.Address;
            mc.Port = hDParam.Port;
            mc.ConnectTimeOut = hDParam.TimeOut;
            mc.ReceiveTimeOut = hDParam.TimeOut;
            start = true;
            Connection();
        }

        public override void Stop()
        {
            start = false;
            task?.Wait(200);
            mc?.ConnectClose();
            ConnStatus = ConnStatus.断线;
        }
        private void Connection()
        {
            //LogHelper.Log(LogType.PC_PLC, "请求连接");
            task = Task.Factory.StartNew(new Action(() =>
            {
                while (start)
                {
                    try
                    {
                        if (ConnStatus == ConnStatus.断线)
                        {
                            OperateResult operate = mc.ConnectServer();
                            if (operate.IsSuccess)
                                ConnStatus = ConnStatus.连接;
                            else
                                ConnStatus = ConnStatus.断线;
                        }
                        else
                        {
                            ConnStatus = ConnStatus.连接;

                            if (!string.IsNullOrEmpty(hDParam.Heartbeat))
                            {
                                ushort val = 1;
                                var op = Write(hDParam.Heartbeat, val);
                                if (!op.IsSuccess)
                                    ConnStatus = ConnStatus.断线;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        ConnStatus = ConnStatus.断线;
                        Log4.Error(ex);
                    }

                    Task.Delay(1000).Wait();
                }
            }), TaskCreationOptions.LongRunning);
        }
        public override OperateResult Write(string address, ushort val)
        {
            return mc.Write(address, val);
        }

        public override OperateResult Write(string address, int val)
        {
            return mc.Write(address, val);
        }

        public override OperateResult Write(string address, bool val)
        {
            return mc.Write(address, val);
        }

        public override OperateResult Write(string address, string val)
        {
            return mc.Write(address, val);
        }

        public override OperateResult Write(string address, byte[] val)
        {
            return mc.Write(address, val);
        }
    }
}
